home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / asm / alib11b.zip / CODE1.ZIP / DISKINFO / RAWREAD.ASM < prev    next >
Assembly Source File  |  1994-10-04  |  10KB  |  403 lines

  1. ;
  2. ; This file contains a collection of runctions to read absolute (low level)
  3. ; disk addresses. 
  4. ;---------------------------------------------------------------------------
  5. ; bump disk address
  6. ;  inputs:  cx,dx = disk address in int13 format
  7. ;           current_param_ptr = ptr to parameters found by cmos check logic
  8. ;  outputs: cx,dx = disk address +1 in int13 format
  9. ;           carry set if at end of disk
  10. ;
  11. bump_address:
  12.     push    ax
  13.     push    bx
  14.     push    si
  15.  
  16.         mov     al,cl                   ;only -bx- can be modified
  17.         and     al,3fh
  18. ;
  19. ;   -al- = sector address
  20.  
  21.         mov     bx,cx                   ;get sector & cyl data
  22.         xchg    bh,bl                   ;
  23.         rol     bh,1
  24.         rol     bh,1
  25.         and     bh,3                    ;remove sector bits
  26. ;
  27. ; -al- = sector address
  28. ; -bx- = track or cyl address
  29. ;
  30.     mov    si,current_param_ptr    ;point at param's from cmos check
  31.         inc     al
  32.         cmp     al,[si.sect_per_tk]    ;check if at end of cyl
  33.         jbe     bump_end2        ;jmp if not at end yet
  34.         call    bump_head
  35.         mov     al,1                    ;start with sector 1
  36. bump_end2:
  37. ;
  38. ; -al- = updated sector address
  39. ; -bx- = updated track address
  40. ; -dh- = updated head
  41. ;
  42.     mov    cl,bh            ;get track high bits
  43.         ror     cl,1                    ;move track
  44.         ror     cl,1                    ;  high bits
  45.         or      cl,al            ;merge sector# in
  46.         mov     ch,bl            ;get track low bits
  47.  
  48.     cmp    bx,[si.last_cyl]    ;check if at end of disk
  49.     jb    bump_exit1
  50.     stc
  51.     jmp    bump_exit2
  52. bump_exit1:
  53.     clc
  54. bump_exit2:
  55.     pop    si
  56.     pop    bx
  57.     pop    ax
  58.     ret
  59. ;------------------------------------------------------------------------
  60. ; bump transfer address
  61. ;
  62. bump_address:
  63.         mov     al,CURRENT_SECTOR_ADR
  64.         inc     al
  65.         cmp     al,cs:[bp].SECTORS_PER_TRACK
  66.         jbe     bump_end2
  67.         mov     ah,CURRENT_DISK_HEAD
  68.         test    ah,0c0h            ;check for extended cyl. adr
  69.         jz    bump_hd1        ;jmp if normal head
  70.         inc     ah
  71.         mov    CURRENT_SECTOR_ADR,1
  72. ;
  73. ; head has extended cyl. address in high bits, bump head
  74. ;
  75.     mov    al,ah            ;save head in -al-
  76.     and    al,3fh            ;isolate head
  77.     cmp    al,cs:[bp].NUMBER_OF_HEADS
  78.     jne    bump_ext1        ;jmp if no head overflow
  79. ;
  80. ; head has overflowed, set it back to zero.
  81. ;
  82.     and    ah,0c0h
  83.     mov    CURRENT_DISK_HEAD,ah
  84. ;
  85. ; bump cyl
  86. ;
  87.     mov    ax,CURRENT_TRACK
  88.     inc    ax            ;bump track
  89.     test    ax,0fc00h        ;check if track overflow
  90.     jz    bump_ext2        ;jmp if no track overflow
  91. ;
  92. ; track (cyl) has overflowed. bump bits in head
  93. ;
  94.     and    ax,3ffh            ;isolate new track bits
  95.     add    CURRENT_DISK_HEAD,040H    ;fix cyl. bits in head
  96.     jmp    bump_ext2
  97. ;
  98. ; update head
  99. ;
  100. bump_ext1:
  101.     mov    CURRENT_DISK_HEAD,ah
  102.     ret
  103. bump_ext2:
  104.     mov    CURRENT_TRACK,ax
  105.     ret
  106.  
  107.        
  108. ;
  109. ; normal processing of head without extended cyl.
  110. ;
  111. bump_hd1:       
  112.         inc     ah
  113.         cmp     ah,cs:[bp].NUMBER_OF_HEADS
  114.         jne     bump_end1
  115.         inc     CURRENT_TRACK
  116.         test    CURRENT_TRACK,0C00H    ;check if track overflow
  117.         jz    bump_end
  118. ;
  119. ; the cyl overflowed. set the high head bits
  120. ;
  121.     mov    CURRENT_TRACK,0        ;set track to 0
  122.     mov    ah,40h            ;bump high head bit
  123.     jmp    bump_end1
  124.     
  125. bump_end:       
  126.         mov     ah,0                    ;start with side 0 again
  127. bump_end1:
  128.         mov     al,1                    ;start with sector 1
  129.         mov     CURRENT_DISK_HEAD,ah
  130. bump_end2:
  131.         mov     CURRENT_SECTOR_ADR,al
  132.         ret
  133.         
  134. ;----------------------------------------------------------------------------
  135. ; subroutine to calculate an abolute disk address
  136. ;   inputs:  cx = disk cyl & sector in int13 format
  137. ;            dh = disk head (high 2 bits can be used for cyl expansion)
  138. ;
  139. ;   outputs:  dx,ax = abs. adr
  140. ;
  141. compute_dsk_abs_adr:
  142.     push    si
  143.     push    bx
  144. ;
  145. ; compute (sectors per cyl) * (number of heads)   to be used later
  146. ;
  147.     push    dx
  148.     mov    si,current_param_ptr    ;get disk parameters
  149.     sub    bx,bx
  150.     mov    bl,[si.sect_per_tk]
  151.     sub    ax,ax
  152.     mov    al,[si.heads]
  153.     mul    bx            ;compute  heads * (sectors per cyl)
  154.     mov    sect_per_cyl,ax
  155.     pop    dx
  156.  
  157.     dec    cx                ;make sectors zero based.
  158.     mov    bl,dh                ;save head
  159.     mov    si,current_param_ptr        ;point at disk parameters
  160.     mov    ax,cx
  161.     xchg    ah,al
  162.     rol    ah,1
  163.     rol    ah,1
  164.     and    ax,3ffh                ;isolate total cyl's  
  165. ;
  166. ; check for extended cyl. bits in head
  167. ;
  168.     test    bl,0c0h
  169.     jz    cda1                ;jmp if normal cyl
  170.     add    ax,1024
  171.     test    bl,080h
  172.     jz    cda1
  173.     add    ax,1024
  174. cda1:
  175.     mul    sect_per_cyl            ;total sectors in whole cyl's
  176. ;
  177. ; process head
  178. ;    
  179.     push    ax
  180.     push    dx
  181.     mov    al,bl
  182. ;
  183. ; DOS 3.3 fdisk has a bug, it sometimes sets the head to one more than it
  184. ; should.  If head is out of bounds, then decrement.
  185. ; This problem only seems to occur on extended partitions.
  186. ;
  187.     and    al,3fh                ;remove cyl. extension bits
  188.     cmp    al,[si.heads]
  189.     jb    head_ok_now
  190.     dec    al
  191. head_ok_now:
  192.  
  193.     mul    [si.sect_per_tk]
  194.     mov    bx,ax
  195.     pop    dx
  196.     pop    ax
  197.     add    ax,bx                ;add in  heads * sect_per_tk
  198.     mov    bx,0
  199.     adc    dx,bx
  200.     
  201.     mov    bl,cl
  202.     and    bx,03fh                ;isolate whole sectors
  203.     add    ax,bx
  204.     mov    bx,0
  205.     adc    dx,bx
  206.  
  207.     pop    bx
  208.     pop    si
  209.     ret
  210.         
  211. ;----------------------------------------------------------------------------
  212. ; compute int13 address from absolute disk address
  213. ;    inputs:  dx,ax = disk absolute address
  214. ;             sect_per_cyl  pre calculated.
  215. ;   outputs:  cx,dh = int13 address 
  216. ;
  217. compute_int13_adr:
  218.     push    si
  219.     push    bx
  220.     mov    si,current_param_ptr        ;point at disk parameters
  221.  
  222.     div    sect_per_cyl            ;ax = cyl  dx=remainder
  223.     mov    cx,ax                ;save cyl
  224.     mov    ax,dx
  225.     div    [si.sect_per_tk]        ;al = heads ah=sector
  226.     mov    dh,al                ;save head
  227.     test    ch,0c0h                ;check for extended cyl
  228.     jz    cia1                ;jmp if normal cyl
  229.     add    dh,40h                ;bump head if large cyl
  230.     test    ch,80h
  231.     jz    cia1                ;jmp if no extra bump
  232.     add    dh,40h
  233.     and    cx,3ffh                ;isolate remaining cyl's
  234. cia1:
  235.     xchg    ch,cl
  236.     ror    cl,1
  237.     ror    cl,1
  238.     or    cl,ah                ;combine sector & cyl high
  239.     inc    cl                ;restore sector start of 1
  240.     pop    bx
  241.     pop    si
  242.     ret    
  243.     
  244. ;----------------------------------------------------------------------------
  245. ; form cyl. adr in -ax-
  246. ;  inputs:  -cx- has int13  cyl & sect
  247. ;           -dh- has head
  248. ;  output:  -ax- has cyl
  249. ;
  250. form_cyl:
  251.     push    si
  252.     mov    si,current_param_ptr        ;point at disk parameters
  253.     mov    ax,cx
  254.     xchg    ah,al
  255.     rol    ah,1
  256.     rol    ah,1
  257.     and    ax,3ffh                ;isolate total cyl's  
  258. ;
  259. ; check for extended cyl. bits in head
  260. ;
  261.     test    dh,0c0h
  262.     jz    fcc1                ;jmp if normal cyl
  263.     add    ax,1024
  264.     test    dh,080h
  265.     jz    fcc1
  266.     add    ax,1024
  267. fcc1:
  268.     pop    si
  269.     ret
  270. ;----------------------------------------------------------------------------
  271. ---------------------------------------------------------------------------
  272. ;
  273. ; compute int13    address    from absolute disk address
  274. ;    inputs:  dx,ax = disk absolute address
  275. ;          sect_per_cyl  pre    calculated. (.shc)
  276. ;   outputs:  cx,dh = int13 address
  277. ;
  278. compute_int13_adr:
  279.     div    pend_shc            ;ax = cyl  dx=remainder
  280.     mov    cx,ax                ;save cyl
  281.     mov    ax,dx
  282.     div    pend_sec_per_track         ;al =    heads ah=sector
  283.     mov    dh,al                ;save head
  284.     test    ch,0c0h                ;check    for extended cyl
  285.     jz    cia1                ;jmp if normal cyl
  286.     add    dh,40h                ;bump head if large cyl
  287.     test    ch,80h
  288.     jz    cia1                ;jmp if no extra bump
  289.     add    dh,40h
  290.     and    cx,3ffh                ;isolate remaining cyl's
  291. cia1:
  292.     xchg    ch,cl
  293.     ror    cl,1
  294.     ror    cl,1
  295.     or    cl,ah                ;combine sector & cyl high
  296.     inc    cl                ;restore sector start of 1
  297.     ret
  298.  
  299. ;---------------------------------------------------------------------------
  300. write_sectors:
  301.     mov    al,CURRENT_SECTOR_COUNT
  302.     mov    ah,3            ;get disk request code
  303.     jmp    short read_sectors2
  304. ;----------------------------------------------------------------------------
  305. read_sectors:
  306.     mov    al,CURRENT_SECTOR_COUNT
  307. read_sectors1:
  308.     mov    ah,2            ;get disk request code
  309. read_sectors2:
  310.     les    bx,CURRENT_USERS_BUFFER ;restore -ES:bx-
  311.  
  312.     add    byte ptr disk_transfers,al    ;update    stat's
  313.     adc    byte ptr disk_transfers+1,0
  314.     jns    read_sectors3            ;jmp if no    overflow
  315.     shr    disk_transfers,1        ;scale stat's
  316.     shr    cache_hits,1
  317. read_sectors3:
  318.     cmp    translate_call,0
  319.     je    read_sectors4            ;jmp if normal disk    read
  320.     test    current_disk_head,0c0h
  321.     jz    read_sectors4            ;jmp if no possible    translation
  322.     push    ax
  323.     mov    dl,current_drive
  324.     mov    dh,0
  325.     mov    ax,0ee00h
  326.     mov    cx,1
  327.     pushf
  328.     call    origional_int13            ;issue translation call
  329.     pop    ax
  330.     mov    dh,CURRENT_DISK_HEAD
  331.     and    dh,3fh                ;remove high head bits
  332.     jmp    short read_sectors5
  333. read_sectors4:
  334.     mov    dh,current_disk_head
  335. read_sectors5:
  336. ;
  337. ; join address into int13 format
  338. ;   inputs  CURRENT_TRACK,CURRENT_SECTOR
  339. ;   output  CX = int13 data
  340. ;
  341.     mov    cl,byte ptr ds:CURRENT_TRACK+1 ;get track hi 2-bits
  342.     ror    cl,1            ;move track
  343.     ror    cl,1            ;  high bits
  344.     or    cl,CURRENT_SECTOR_ADR    ;merge sector# in
  345.     mov    ch,byte ptr ds:CURRENT_TRACK    ;get track low bits
  346.  
  347.     mov    dl,CURRENT_DRIVE
  348.     pushf                ;
  349.     call    cs:origional_int13
  350.     cmp    ah,0
  351.     jz    rs_exit            ;jmp if no disk errors
  352.     stc
  353. rs_exit:
  354.     ret
  355.  
  356. ;----------------------------------------------------------------------------
  357. ; subroutine to    calculate sector number
  358. ; inputs:  dh =    int13 head
  359. ;       ch =    int13 cyl
  360. ;       cl =    int13 cyl hi + sector
  361. ; outupts: dx,ax = sector#
  362. ;
  363. build_sector_number:
  364.     mov    dl,cl            ;get sector#
  365.     and    dl,3fh            ;isolate sector#
  366.     mov    current_sector_adr,dl
  367.     dec    dl            ;zero    base sector#
  368.  
  369.     mov    dl,dh            ;get head#
  370.     mov    current_disk_head,dl
  371.     and    dl,3fh            ;isolate head#
  372.  
  373.     and    dh,0c0h            ;isolate    cyl bits 11-10
  374.     and    cl,0c0h            ;isolate    cyl bits 9-8
  375.     rol    dh,1
  376.     rol    dh,1            ;position bits 11-10
  377.     or    cl,dh            ;merge bits    11-10-9-8
  378.     rol    cl,1
  379.     rol    cl,1
  380.     xchg    cl,ch
  381.     mov    current_track,cx        ;save cyl#
  382. ;
  383. ; compute big sector#  (cyl*shc) + (head*sectors_per_track) + sector#
  384. ;               Note: shc = (sectors_per_track *    heads)
  385. ;
  386.     mov    al,current_drv_data.sectors_per_track
  387.     mul    dl            ; (sectors_per_track * current_disk_head)
  388.     push    ax            ;save head# * sectors_per_track
  389.  
  390.     mov    ax,current_drv_data.shc    ;get (total_heads * sect_per_track)
  391.     mul    cx            ; (cyl * shc)
  392.     pop    cx
  393.     add    ax,cx            ;(cyl*sch)    + (head    * sectors_per_track)
  394.     adc    dx,0
  395.  
  396.     mov    cl,current_sector_adr
  397.     dec    cl            ;make    sectors    zero based
  398.     add    al,cl
  399.     adc    ah,0
  400.     adc    dx,0
  401.  
  402.     ret
  403.